 //-----------------------------------------------------------------------------
//
//Copyright(c) 2020, ThorsianWay Technologies Co, Ltd
//All rights reserved.
//
//IP Name       :   pixel_shader
//File Name     :   clz_64.v
//Module name   :   clz_64
//Full name     :   64 bit unsigned numbei leading zero count
//
//Author        :   zha daolu
//Email         :   
//Data          :   2020/5/13
//Version       :   V1.00
//
//Abstract      :   
//                  
//Called  by    :   GPU
//
//Modification history
//-----------------------------------------------------
//1.00: intial version 
//
//-----------------------------------------------------------------------------    
module clz_64(
        Data_in,
        LZB_out
        );
        input   [63:0]  Data_in;
        output  [ 6:0]  LZB_out;
        
        reg             [ 5:0]  First_One_Pos;

        reg     [31:0]  Data_32;
        reg             [16:0]  Data_16;
        reg             [ 7:0]  Data_8;
        reg             [ 3:0]  Data_4;
        reg             [ 1:0]  Data_2;
        
       // 1st 
        always @ (Data_in)
        begin
                if(Data_in[63:32] == 0)
                begin
                        Data_32 = Data_in[31:0];
                        First_One_Pos[5] = 1'b0;
                end
                else
                begin
                        Data_32= Data_in[63:32];
                        First_One_Pos[5] = 1'b1;
                end     
        end 

        // 2nd 
        always @ (Data_32)
        begin
                if(Data_32[31:16] == 0)
                begin
                        Data_16 = Data_32[15:0];
                        First_One_Pos[4] = 1'b0;
                end
                else
                begin
                        Data_16 = Data_32[31:16];
                        First_One_Pos[4] = 1'b1;
                end     
        end
        // 3nd
        always @ (Data_16)
        begin
                if(Data_16[15:8] == 0)
                begin
                        Data_8 = Data_16[7:0];
                        First_One_Pos[3] = 1'b0;
                end
                else
                begin
                        Data_8 = Data_16[15:8];
                        First_One_Pos[3] = 1'b1;
                end     
        end
        // 4th
        always @ (Data_8)
        begin
                if(Data_8[7:4] == 0)
                begin
                        Data_4 = Data_8[3:0];
                        First_One_Pos[2] = 1'b0;
                end
                else
                begin
                        Data_4 = Data_8[7:4];
                        First_One_Pos[2] = 1'b1;
                end     
        end
        // 5th
        always @ (Data_4)
        begin   
                if(Data_4[3:2] == 0)
                begin
                        Data_2 = Data_4[1:0];
                        First_One_Pos[1] = 1'b0;
                end
                else
                begin
                        Data_2 = Data_4[3:2];
                        First_One_Pos[1] = 1'b1;
                end     
        end
        // 6th
        always @ (Data_2)
        begin
                First_One_Pos[0] = Data_2[1];
        end
        
        assign LZB_out = (Data_in == 0)? 6'b100000 : {1'b0, (~First_One_Pos)};
        
endmodule
